package com.hy.lightning.ds.redis;

import java.util.Arrays;
import java.util.List;
import java.util.Set;

import org.apache.log4j.Logger;

import com.hy.lightning.commons.utils.ObjectUtil;
import com.hy.lightning.ds.RedisDataSource;
import com.hy.lightning.ds.RedisSession;

import redis.clients.jedis.Jedis;

public class BaseRedisSession implements RedisSession {

	private RedisDataSource redisDS = new BaseRedisDataSource();
	
	public String redisDataSourceKey;
	
	private Logger logger = Logger.getLogger(getClass());
	
	public BaseRedisSession(String redisDataSourceKey) {
		this.redisDataSourceKey = redisDataSourceKey;
	}
	
	public BaseRedisSession() {
		this("local");
	}
	
	public static void main(String[] args) {
		RedisConf redisConf = new RedisConf("local", "test.sharetasty.com", "49BA59ABBE56E057");
		redisConf.setIndex(1);
		RedisDataSource.initDataSource(redisConf);
		RedisSession redisService = new BaseRedisSession();
		long i = redisService.expire("name", "hy", 60);
		System.out.println(i);
	}
	
	@Override
	public long expire(String key, String value, int seconds) {
		Jedis jedis = redisDS.getJedis(redisDataSourceKey);
		try {
			if ("OK".equals(jedis.set(key, value))) {
				logger.info(String.format("jedis expire value key:%s, value:%s, second:%s", key, value, seconds));
				return jedis.expire(key, seconds);
			}
		} finally {
			if(jedis != null) jedis.close();
		}
		return 0;
	}

	@Override
	public long getKeyTime(String key) {
		Jedis jedis = redisDS.getJedis(redisDataSourceKey);
		try {
			if (key == null)
				return 0;
			return jedis.ttl(key);
		} finally {
			if(jedis != null) jedis.close();
		}
	}

	@Override
	public int set(String key, String value) {
		Jedis jedis = redisDS.getJedis(redisDataSourceKey);
		try {
			if (key == null)
				return 0;
			value = value == null ? "" : value;
			logger.info(String.format("jedis set value key:%s,value:%s", key, value));
			return jedis.set(key, value).equals("OK") ? 1 : 0;
		} finally {
			if(jedis != null) jedis.close();
		}
	}

	@Override
	public long remove(String... keys) {
		Jedis jedis = redisDS.getJedis(redisDataSourceKey);
		try {
			logger.info("jedis remove keys:"+ Arrays.deepToString(keys));
			return jedis.del(keys);
		} finally {
			if(jedis != null) jedis.close();
		}
	}

	@Override
	public String getValue(String key) {
		Jedis jedis = redisDS.getJedis(redisDataSourceKey);
		try {
			if (key == null)
				return null;
			return jedis.get(key);
		} finally {
			if(jedis != null) jedis.close();
		}
	}

	@Override
	public Set<String> getKeys(String key) {
		Jedis jedis = redisDS.getJedis(redisDataSourceKey);
		try {
			return jedis.keys(key);
		} finally {
			if(jedis != null) jedis.close();
		}
	}

	@Override
	public boolean containsKey(String key) {
		Jedis jedis = redisDS.getJedis(redisDataSourceKey);
		try {
			if (key == null)
				return false;
			return jedis.exists(key);
		} finally {
			if(jedis != null) jedis.close();
		}
	}

	@Override
	public void setObject(String key, Object object) {
		Jedis jedis = redisDS.getJedis(redisDataSourceKey);
		try {
			if (key == null || object == null)
				return;
			byte[] bs = ObjectUtil.serialize(object);
			jedis.set(key.getBytes(), bs);
		} finally {
			if(jedis != null)
				jedis.close();
		}

	}

	@Override
	public long expire(String key, int seconds) {
		Jedis jedis = redisDS.getJedis(redisDataSourceKey);
		try {
			return jedis.expire(key, seconds);
		} finally {
			if(jedis != null) jedis.close();
		}
	}
	
	@Override
	public Object getObject(String key) {
		Jedis jedis = redisDS.getJedis(redisDataSourceKey);
		try {
			byte[] bytes = jedis.get(key.getBytes());
			if(bytes != null)
				return ObjectUtil.unserialize(bytes);
		} finally {
			if(jedis != null) jedis.close();
		}
		return null;
	}

	@Override
	public boolean setBatch(List<String> keys, List<String> values) {
		for(int i = 0; i< keys.size(); i++) {
			int r = set(keys.get(i), values.get(i));
			if(r != 1) {
				for(int j = 0; j < i; j++) {
					remove(keys.get(j));
				}
				return false;
			}
		}
		return true;
	}
}
